#pragma once

#include "Common.h"
#include <iostream>
#include <memory>
#include <string>
#include <sstream>
#include <jsoncpp/json/json.h>

using std::cout;
using std::endl;
using std::ostringstream;
using std::string;
using std::unique_ptr;

namespace rpc
{
// log
#define LDBG 0
#define LINF 1
#define LERR 2
#define LDEFAULT LINF

#define LOG(level, format, ...)                                             \
    {                                                                       \
        if (level >= LDEFAULT)                                              \
        {                                                                   \
            time_t t = time(NULL);                                          \
            struct tm *lt = localtime(&t);                                  \
            char time_tmp[32] = {0};                                        \
            strftime(time_tmp, 31, "%m-%d %T", lt);                         \
            fprintf(stdout, "[%s][%s:%d] " format "\n", time_tmp, __FILE__, \
                    __LINE__, ##__VA_ARGS__);                               \
        }                                                                   \
    }

#define DLOG(format, ...) LOG(LDBG, format, ##__VA_ARGS__);
#define ILOG(format, ...) LOG(LINF, format, ##__VA_ARGS__);
#define ELOG(format, ...) LOG(LERR, format, ##__VA_ARGS__);
    class JsonUtil
    {

    public:
        static bool serialize(Json::Value &value, string &str)
        {
            Json::StreamWriterBuilder swb;
            unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

            ostringstream oss;
            if (sw->write(value, &oss))
            {
                ELOG("json serialize error");
                return false;
            }

            str = oss.str();
            return true;
        }

        static bool unserialize(const string &str, Json::Value &value)
        {
            Json::CharReaderBuilder crb;

            unique_ptr<Json::CharReader> cr(crb.newCharReader());
            string err;
            if (!cr->parse(str.c_str(), str.c_str() + str.size(), &value, &err))
            {

                ELOG("json unserialize error");

                return false;
            }

            return true;
        }

    }; // JsonUtil

} // rpc